export type RequestOptions = {
	uuid ?: string, // 请求的唯一标识符。用于取消请求。可选。
	baseURL ?: string, // 设置请求的基础URL。
	url ?: string, // 请求的URL。必填。
	custom ?: any, // 自定义参数 方便在 hook 操作拦截
	data ?: any, // 请求的数据。可选。
	method ?: string, // 请求的方法。可选，默认为GET。
	header ?: any, // 请求的头部。可选。
	timeout ?: number, // 请求的超时时间。可选，默认为60000，表示不设置超时时间。
	dataType ?: string, // 响应的数据类型。可选，默认为json。
	responseType ?: string, // 响应的类型。可选，默认为text。 支付宝小程序不支持
	sslVerify ?: boolean, // 是否验证SSL证书。可选，默认为true。 仅App安卓端支持（HBuilderX 2.3.3+），不支持离线打包
	withCredentials ?: boolean, // 是否携带凭证（cookies）。可选，默认为false。 仅H5支持（HBuilderX 2.6.15+）
	firstIpv4 ?: boolean, // DNS解析时是否优先使用ipv4。可选，默认为false。仅 App-Android 支持 (HBuilderX 2.8.0+)。
	enableHttp2 ?: boolean, // 是否开启http2。可选，默认为false。仅微信小程序支持。
	enableQuic ?: boolean, // 是否开启quic。可选，默认为false。仅微信小程序支持。
	enableCache ?: boolean, // 是否开启cache。可选，默认为false。仅微信小程序和抖音小程序支持。
	enableHttpDNS ?: boolean, // 是否开启HttpDNS服务。可选，默认为false。仅微信小程序支持。
	httpDNSServiceId ?: string, // HttpDNS服务Id。仅当enableHttpDNS为true时有效。仅微信小程序支持。
	enableChunked ?: boolean, // 是否开启transfer-encoding chunked。可选，默认为false。仅微信小程序支持。
	forceCellularNetwork ?: boolean, // 是否强制使用移动网络发送请求。可选，默认为false。仅微信小程序支持。
	enableCookie ?: boolean, // 是否开启cookie。可选，默认为false。仅支付宝小程序支持。
	cloudCache ?: boolean, // 是否开启云加速。可选，默认为false。仅百度小程序支持。
	defer ?: boolean, // 是否延时发送请求。可选，默认为false。仅百度小程序支持。
}

export class UniRequest {
	constructor(config ?: object) {
		this.config = Object.assign({}, this.config, config)
	}

	config : any = {
		// 设置全局的请求配置。
		baseURL: 'https://www.example.com', // 设置请求的基础URL。
		header: {}, // 设置全局的请求头部。
		method: 'GET', // 设置全局的请求方法。
		dataType: 'json', // 设置全局的响应数据类型。
		custom: {
			auth: true, // 默认所有请求都携带 token userid
		},
		timeout: 60000, // 设置全局的请求超时时间。
		// #ifndef  MP-ALIPAY 
		responseType: 'text', // 设置全局的响应类型。 支付宝小程序不支持。
		// #endif
		// #ifdef APP
		sslVerify: true, // 设置全局的SSL证书验证。仅App支持。不支持离线打包。HBuilderX 2.3.3+。
		// #endif
		// #ifdef H5
		withCredentials: false, // 设置全局的请求是否携带凭证（cookies）。仅H5支持。HBuilderX 2.6.15+。
		// #endif
		// #ifdef APP-ANDROID
		firstIpv4: false, // 设置全局的DNS解析时是否优先使用ipv4。仅 App-Android 支持 (HBuilderX 2.8.0+)。
		// #endif
		// #ifdef MP-WEIXIN || MP-TOUTIAO
		enableCache: false, // 设置全局的请求是否开启cache。仅微信小程序和抖音小程序支持。
		// #endif
		// #ifdef MP-WEIXIN
		enableHttpDNS: false, // 设置全局的请求是否开启HttpDNS服务。仅微信小程序支持。
		httpDNSServiceId: '', // 设置全局的HttpDNS服务Id。仅当enableHttpDNS为true时有效。仅微信小程序支持。
		enableChunked: false, // 设置全局的请求是否开启transfer-encoding chunked。仅微信小程序支持。
		forceCellularNetwork: false, // 设置全局的请求是否强制使用移动网络发送请求。仅微信小程序支持。
		enableHttp2: false, // 设置全局的请求是否开启http2。仅微信小程序支持。
		enableQuic: false, // 设置全局的请求是否开启quic。仅微信小程序支持。
		// #endif
		// #ifdef MP-ALIPAY 
		enableCookie: false, // 设置全局的请求是否开启cookie。仅支付宝小程序支持。
		// #endif
		// #ifdef MP-BAIDU
		cloudCache: false, // 设置全局的请求是否开启云加速。仅百度小程序支持。
		defer: false, // 设置全局的请求是否延时发送。仅百度小程序支持。
		// #endif
	};
	// 拦截器
	interceptors = {
		request: (config : RequestOptions) : RequestOptions => {
			return config; // 请求拦截器，在发送请求前执行。
		}, // 请求拦截器，在发送请求前执行。
		response: (response : any) : any => {
			return response;
		}, // 响应拦截器，在收到响应后执行。
		fail: (err : any) : any => {
			return err;
		}, // 请求失败时执行。
	};

	requestTasks : any = {};
	// 请求对象

	saveRequestTask(key : string, requestTask : any) {
		// 将请求任务保存到数组中，以便可以取消请求。
		this.requestTasks[key] = requestTask;
	}
	abortRequest(key : string) : void {
		// 取消请求方法，传入请求的url即可取消对应的请求。
		this.requestTasks[key].abort();
	}
	// 请求方法
	request(options : RequestOptions) {
		return new Promise((resolve, reject) => {
			const temp = Object.assign({}, this.config, options);
			const uniOptions = this.interceptors.request(temp);
			let url = uniOptions.baseURL + uniOptions.url; // 拼接请求的url。
			let requestTask = uni.request({
				...uniOptions as any,
				url: url, //仅为示例，并非真实接口地址。
				success: (res : any) => {
					if (res.statusCode >= 200 && res.statusCode <= 400) {
						resolve(this.interceptors.response(res.data))
					} else {
						reject(this.interceptors.fail(res));
					}
					// 请求成功

				},
				fail: (err : any) => {
					reject(this.interceptors.fail(err));
					// 请求失败时，执行相应的操作。
				}
			});
			if (options.uuid) {
				this.saveRequestTask(options.uuid, requestTask)
			}
		})
	}
} (this)

export default new UniRequest();